﻿#region

using System;
using System.Collections.Generic;
using System.Linq;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

using Pob.CustomEventArgs;
using Pob.GameObjects;

#endregion

namespace Pob.ScreenManagement.OptionsScreens
{
    public delegate void PlayerScreenMenuItemEnteredEvent(object obj, MenuItemPickedEventArgs e);

    public class PlayerOptionsScreen : ScreenBase
    {
        #region Fields

        private readonly MenuItem _back;

        private readonly MenuControl _control;

        private readonly MenuItemGroup _menuItemGroup;

        private readonly Player _player;

        private readonly List<MenuItem> _selectableItems;

        private bool _firstUpdate = true;

        #endregion

        #region Constructors and Destructors

        public PlayerOptionsScreen(Game game, PlayerScreenMenuItemEnteredEvent eventHandler, Player player)
            : base(game)
        {
            _back = new MenuItem(game, new DrawString(game, GameContent.FontMenuItems, "back", new Vector2(Settings.Width / 2f, (Settings.Height / 2) + 200), Color.White, selected: false, drawStringMode: DrawStringMode.WithSelected), OnBackItem);

            _player = player;

            _menuItemGroup = new MenuItemGroup(game, GameContent.FontMenuItems, Color.White, drawStringMode: DrawStringMode.WithSelected, oringeMode: OringeMode.TopLeft);
            _menuItemGroup.AddExtended("player name", MenuItemExtendedMode.String, OnPlayerName, _player.Name, true);
            _menuItemGroup.AddExtended("key up", MenuItemExtendedMode.Key, OnKeyUp, _player.KeyUp.ToString());
            _menuItemGroup.AddExtended("key down", MenuItemExtendedMode.Key, OnKeyDown, _player.KeyDown.ToString());
            _menuItemGroup.AddExtended("power up", MenuItemExtendedMode.Key, OnKeyPowerUp, _player.KeyPowerUp.ToString());

            _selectableItems = new List<MenuItem>();
            _selectableItems.AddRange(_menuItemGroup.MenuItems);
            _selectableItems.Add(_back);
            
            MyComponents.AddRange(_selectableItems);

            _control = new MenuControl(_selectableItems);
            PlayerScreenMenuItemPicked += eventHandler;
        }

        #endregion

        #region Public Events

        public event PlayerScreenMenuItemEnteredEvent PlayerScreenMenuItemPicked;

        #endregion

        #region Public Methods and Operators

        public override void Initialize()
        {
            _menuItemGroup.CalculatePositions();

            AddRange(MyComponents);

            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            if (!_firstUpdate)
            {
                _control.Update(gameTime);
            }
            else
            {
                // Input-Abfrage beginnt erst, wenn keine Keys mehr aus dem vorherigen Screen gedrückt sind
                _firstUpdate = Keyboard.GetState().GetPressedKeys().Length > 0;
            }
        }

        #endregion

        #region Methods

        private Keys GetKey(string value)
        {
            var keys = Enum.GetValues(typeof(Keys));

            return keys.Cast<Keys>().FirstOrDefault(key => key.ToString() == value);
        }

        private void OnBackItem(object obj, MenuItemPickedEventArgs args)
        {
            _player.Name = _menuItemGroup.MenuItems[0].ItemExtension.Text;
            _player.KeyUp = GetKey(_menuItemGroup.MenuItems[1].ItemExtension.Text);
            _player.KeyDown = GetKey(_menuItemGroup.MenuItems[2].ItemExtension.Text);

            if (PlayerScreenMenuItemPicked != null)
            {
                PlayerScreenMenuItemPicked(this, new MenuItemPickedEventArgs((MenuItem)obj)
                    {
                        MenuState = MenuStates.PlayerOptionsBack
                    });
            }
        }

        private void OnKeyDown(object obj, MenuItemPickedEventArgs args)
        {
            _menuItemGroup.MenuItems[2].ItemExtension.Selected = !_menuItemGroup.MenuItems[2].ItemExtension.Selected;
        }

        private void OnKeyPowerUp(object obj, MenuItemPickedEventArgs args)
        {
            _menuItemGroup.MenuItems[3].ItemExtension.Selected = !_menuItemGroup.MenuItems[3].ItemExtension.Selected;
        }

        private void OnKeyUp(object obj, MenuItemPickedEventArgs args)
        {
            _menuItemGroup.MenuItems[1].ItemExtension.Selected = !_menuItemGroup.MenuItems[1].ItemExtension.Selected;
        }

        private void OnPlayerName(object obj, MenuItemPickedEventArgs args)
        {
            _menuItemGroup.MenuItems[0].ItemExtension.Selected = !_menuItemGroup.MenuItems[0].ItemExtension.Selected;
        }

        #endregion
    }
}